#ifndef USERMANAGER_H
#define USERMANAGER_H

#include <QObject>
#include <QString>
#include <QCryptographicHash>
#include <QDateTime>
#include <QUuid>
#include <QDebug>
#include <memory>
#include "../data/models.h"
#include "../data/datamanager.h"
#include "../utils/errorhandler.h"

/**
 * @brief 用户管理器
 * 
 * 负责用户注册、登录、认证等功能
 * 提供密码加密、会话管理、权限验证等服务
 */

namespace RestaurantSystem {

/**
 * @brief 认证结果枚举
 */
enum class AuthResult {
    SUCCESS = 0,           // 认证成功
    INVALID_CREDENTIALS,   // 凭据无效
    USER_NOT_FOUND,       // 用户不存在
    USER_ALREADY_EXISTS,  // 用户已存在
    WEAK_PASSWORD,        // 密码强度不足
    INVALID_USERNAME,     // 用户名格式无效
    SYSTEM_ERROR          // 系统错误
};

/**
 * @brief 用户会话信息
 */
struct UserSession {
    QString userId;
    QString username;
    bool isAdmin;
    QDateTime loginTime;
    QDateTime lastActivity;
    
    UserSession() : isAdmin(false) {}
    UserSession(const QString& id, const QString& name, bool admin) 
        : userId(id), username(name), isAdmin(admin), 
          loginTime(QDateTime::currentDateTime()),
          lastActivity(QDateTime::currentDateTime()) {}
    
    bool isValid() const {
        return !userId.isEmpty() && !username.isEmpty();
    }
    
    bool isExpired(int sessionTimeoutMinutes = 120) const {
        return lastActivity.addSecs(sessionTimeoutMinutes * 60) < QDateTime::currentDateTime();
    }
    
    void updateActivity() {
        lastActivity = QDateTime::currentDateTime();
    }
};

/**
 * @brief 用户管理器类
 */
class UserManager : public QObject {
    Q_OBJECT
    
public:
    explicit UserManager(QObject* parent = nullptr);
    ~UserManager();
    
    /**
     * @brief 获取单例实例
     */
    static UserManager& instance();
    
    /**
     * @brief 初始化用户管理器
     * @return 初始化是否成功
     */
    bool initialize();
    
    // ========================================================================
    // 顾客管理
    // ========================================================================
    
    /**
     * @brief 注册新顾客
     * @param username 用户名
     * @param password 密码
     * @param email 邮箱(可选)
     * @return 认证结果
     */
    AuthResult registerCustomer(const QString& username, const QString& password, const QString& email = "");
    
    /**
     * @brief 顾客登录
     * @param username 用户名
     * @param password 密码
     * @return 认证结果
     */
    AuthResult loginCustomer(const QString& username, const QString& password);
    
    /**
     * @brief 修改顾客密码
     * @param oldPassword 旧密码
     * @param newPassword 新密码
     * @return 操作是否成功
     */
    bool changeCustomerPassword(const QString& oldPassword, const QString& newPassword);
    
    /**
     * @brief 更新顾客信息
     * @param customer 顾客信息
     * @return 操作是否成功
     */
    bool updateCustomerInfo(const Customer& customer);
    
    /**
     * @brief 删除顾客账户
     * @param password 确认密码
     * @return 操作是否成功
     */
    bool deleteCustomerAccount(const QString& password);
    
    // ========================================================================
    // 管理员管理
    // ========================================================================
    
    /**
     * @brief 管理员登录
     * @param password 管理员密码
     * @return 认证结果
     */
    AuthResult loginAdmin(const QString& password);
    
    /**
     * @brief 修改管理员密码
     * @param oldPassword 旧密码
     * @param newPassword 新密码
     * @return 操作是否成功
     */
    bool changeAdminPassword(const QString& oldPassword, const QString& newPassword);
    
    /**
     * @brief 重置管理员密码(紧急情况使用)
     * @param newPassword 新密码
     * @return 操作是否成功
     */
    bool resetAdminPassword(const QString& newPassword);
    
    // ========================================================================
    // 会话管理
    // ========================================================================
    
    /**
     * @brief 获取当前用户会话
     * @return 用户会话信息
     */
    UserSession getCurrentSession() const { return m_currentSession; }
    
    /**
     * @brief 检查是否已登录
     * @return 是否已登录
     */
    bool isLoggedIn() const { return m_currentSession.isValid() && !m_currentSession.isExpired(); }
    
    /**
     * @brief 检查是否为管理员
     * @return 是否为管理员
     */
    bool isAdmin() const { return isLoggedIn() && m_currentSession.isAdmin; }
    
    /**
     * @brief 获取当前用户ID
     * @return 用户ID，未登录返回空字符串
     */
    QString getCurrentUserId() const { return isLoggedIn() ? m_currentSession.userId : QString(); }
    
    /**
     * @brief 获取当前用户名
     * @return 用户名，未登录返回空字符串
     */
    QString getCurrentUsername() const { return isLoggedIn() ? m_currentSession.username : QString(); }
    
    /**
     * @brief 更新会话活动时间
     */
    void updateSessionActivity();
    
    /**
     * @brief 用户注销
     */
    void logout();
    
    // ========================================================================
    // 用户信息管理 (新增)
    // ========================================================================
    
    /**
     * @brief 根据ID获取用户信息
     * @param userId 用户ID
     * @return 用户信息，未找到则返回无效的Customer对象
     */
    Customer getUserById(const QString& userId);

    /**
     * @brief 根据用户名获取用户ID
     * @param username 用户名
     * @return 用户ID，未找到则返回空字符串
     */
    QString getUserIdByUsername(const QString& username);
    
    /**
     * @brief 更新用户信息
     * @param userId 用户ID
     * @param updatedInfo 更新的用户信息
     * @return 更新结果
     */
    AuthResult updateUserInfo(const QString& userId, const Customer& updatedInfo);
    
    /**
     * @brief 修改用户密码
     * @param userId 用户ID
     * @param oldPassword 原密码
     * @param newPassword 新密码
     * @return 修改结果
     */
    AuthResult changePassword(const QString& userId, const QString& oldPassword, const QString& newPassword);
    
    /**
     * @brief 验证密码强度
     * @param password 密码
     * @return 是否满足强度要求
     */
    bool validatePasswordStrength(const QString& password);

    /**
     * @brief 验证当前用户的密码
     * @param userId 用户ID
     * @param password 要验证的密码
     * @return 密码是否正确
     */
    bool verifyCurrentUserPassword(const QString& userId, const QString& password);
    
    /**
     * @brief 检查会话是否过期
     * @return 是否过期
     */
    bool isSessionExpired() const { return m_currentSession.isExpired(m_sessionTimeoutMinutes); }
    
    /**
     * @brief 设置会话超时时间
     * @param minutes 超时时间(分钟)
     */
    void setSessionTimeout(int minutes) { m_sessionTimeoutMinutes = minutes; }
    
    // ========================================================================
    // 密码和安全
    // ========================================================================
    
    /**
     * @brief 验证密码强度
     * @param password 密码
     * @return 是否满足强度要求
     */
    bool isPasswordStrong(const QString& password) const;
    
    /**
     * @brief 获取密码强度要求描述
     * @return 要求描述
     */
    QString getPasswordRequirements() const;
    
    /**
     * @brief 验证用户名格式
     * @param username 用户名
     * @return 是否格式正确
     */
    bool isUsernameValid(const QString& username) const;
    
    /**
     * @brief 检查用户名是否已存在
     * @param username 用户名
     * @return 是否已存在
     */
    bool isUsernameExists(const QString& username) const;
    
    /**
     * @brief 生成密码哈希值
     * @param password 原始密码
     * @param salt 盐值
     * @return 哈希值
     */
    static QString generatePasswordHash(const QString& password, const QString& salt = "");
    
    /**
     * @brief 验证密码
     * @param password 原始密码
     * @param hash 存储的哈希值
     * @return 是否匹配
     */
    static bool verifyPassword(const QString& password, const QString& hash);
    
    /**
     * @brief 生成随机盐值
     * @return 盐值字符串
     */
    static QString generateSalt();
    
    // ========================================================================
    // 辅助方法
    // ========================================================================
    
    /**
     * @brief 获取认证结果描述
     * @param result 认证结果
     * @return 描述字符串
     */
    static QString getAuthResultMessage(AuthResult result);
    
    /**
     * @brief 生成唯一用户ID
     * @return 用户ID
     */
    static QString generateUserId();
    
    // ========================================================================
    // 管理员用户管理功能 (新增)
    // ========================================================================
    
    /**
     * @brief 获取所有顾客列表 (管理员功能)
     * @return 所有顾客列表
     */
    QList<Customer> getAllCustomers();
    
    /**
     * @brief 重置顾客密码 (管理员功能)
     * @param customerId 顾客ID
     * @param newPassword 新密码，为空则使用默认密码
     * @return 操作是否成功
     */
    bool resetCustomerPassword(const QString& customerId, const QString& newPassword = "abc123456");
    
    /**
     * @brief 更新顾客状态 (管理员功能)
     * @param customerId 顾客ID
     * @param active 是否激活
     * @return 操作是否成功
     */
    bool updateCustomerStatus(const QString& customerId, bool active);
    
    /**
     * @brief 获取顾客统计信息 (管理员功能)
     * @return 统计信息结构
     */
    struct CustomerStatistics {
        int totalCustomers;
        int activeCustomers;
        int newCustomers;  // 最近7天注册
        int inactiveCustomers;
        
        CustomerStatistics() : totalCustomers(0), activeCustomers(0), newCustomers(0), inactiveCustomers(0) {}
    };
    CustomerStatistics getCustomerStatistics();

signals:
    /**
     * @brief 用户注册成功信号
     * @param user 注册的用户信息
     */
    void userRegistered(const Customer& user);
    
    /**
     * @brief 用户登录成功信号
     * @param userId 用户ID
     * @param username 用户名
     * @param isAdmin 是否为管理员
     */
    void userLoggedIn(const QString& userId, const QString& username, bool isAdmin);
    
    /**
     * @brief 用户注销信号
     * @param userId 用户ID
     */
    void userLoggedOut(const QString& userId);
    
    /**
     * @brief 用户信息更新信号
     * @param userId 用户ID
     */
    void userInfoUpdated(const QString& userId);
    
    /**
     * @brief 密码修改信号
     * @param userId 用户ID
     */
    void passwordChanged(const QString& userId);
    
    /**
     * @brief 会话即将过期信号
     * @param minutesLeft 剩余分钟数
     */
    void sessionExpiring(int minutesLeft);
    
    /**
     * @brief 会话已过期信号
     */
    void sessionExpired();
    
    /**
     * @brief 认证失败信号
     * @param result 失败原因
     * @param username 用户名
     */
    void authenticationFailed(AuthResult result, const QString& username);

public slots:
    /**
     * @brief 检查会话状态
     */
    void checkSessionStatus();

private slots:
    void onSessionCheckTimer();

private:
    /**
     * @brief 创建用户会话
     * @param userId 用户ID
     * @param username 用户名
     * @param isAdmin 是否为管理员
     */
    void createSession(const QString& userId, const QString& username, bool isAdmin);
    
    /**
     * @brief 清除当前会话
     */
    void clearSession();
    
    /**
     * @brief 发送认证失败信号
     * @param result 失败原因
     * @param username 用户名
     */
    void emitAuthenticationFailed(AuthResult result, const QString& username);

private:
    static UserManager* s_instance;
    
    DataManager* m_dataManager;
    UserSession m_currentSession;
    
    // 会话管理
    int m_sessionTimeoutMinutes;
    QTimer* m_sessionCheckTimer;
    
    // 密码策略
    int m_minPasswordLength;
    bool m_requireUppercase;
    bool m_requireLowercase;
    bool m_requireDigits;
    bool m_requireSpecialChars;
    
    // 状态标识
    bool m_isInitialized;
    
    // 默认管理员密码
    static const QString DEFAULT_ADMIN_PASSWORD;
    static const QString PASSWORD_SALT_PREFIX;
};

} // namespace RestaurantSystem

#endif // USERMANAGER_H
